import { defineComponent, type PropType, ref, watch } from "vue";
import { useIntervalFn } from "@vueuse/core";
import { isNumber, isObject, isString } from "@pureadmin/utils";
import { formatToDate, formatToDateTime } from "@/utils/date";
import dayjs from "dayjs";

export default defineComponent({
  name: "TimeAgo",
  props: {
    value: {
      type: [Number, String, Date],
      required: true
    },
    step: {
      type: Number,
      default: 30
    },
    mode: {
      type: String as PropType<"date" | "datetime" | "relative">,
      default: "relative"
    }
  },
  setup(props) {
    const ONE_SECONDS = 1000;
    const ONE_MINUTES = ONE_SECONDS * 60;
    const ONE_HOUR = ONE_MINUTES * 60;
    const ONE_DAY = ONE_HOUR * 24;

    const date = ref("");

    useIntervalFn(setTime, props.step * ONE_SECONDS);

    watch(
      () => props.value,
      () => {
        setTime();
      },
      { immediate: true }
    );

    function getTime() {
      const { value } = props;
      let time = 0;
      if (isNumber(value)) {
        const timestamp = value.toString().length > 10 ? value : value * 1000;
        time = new Date(timestamp).getTime();
      } else if (isString(value)) {
        time = new Date(value).getTime();
      } else if (isObject(value)) {
        time = value.getTime();
      }
      return time;
    }

    function setTime() {
      const { mode, value } = props;
      const time = getTime();
      if (mode === "relative") {
        date.value = getRelativeTime(time);
      } else {
        if (mode === "datetime") {
          date.value = formatToDateTime(value);
        } else if (mode === "date") {
          date.value = formatToDate(value);
        }
      }
    }

    function getRelativeTime(timeStamp: number) {
      const currentTime = new Date().getTime();

      // Determine whether the incoming timestamp is earlier than the current timestamp
      const isBefore = dayjs(timeStamp).isBefore(currentTime);

      let diff = currentTime - timeStamp;
      if (!isBefore) {
        diff = -diff;
      }

      let resStr: string;
      let dirStr = isBefore ? "前" : "后";

      if (diff < ONE_SECONDS) {
        resStr = "刚刚";
        // Less than or equal to 59 seconds
      } else if (diff < ONE_MINUTES) {
        resStr = parseInt(diff / ONE_SECONDS) + "秒" + dirStr;
        // More than 59 seconds, less than or equal to 59 minutes and 59 seconds
      } else if (diff >= ONE_MINUTES && diff < ONE_HOUR) {
        resStr = Math.floor(diff / ONE_MINUTES) + "分钟" + dirStr;
        // More than 59 minutes and 59 seconds, less than or equal to 23 hours, 59 minutes and 59 seconds
      } else if (diff >= ONE_HOUR && diff < ONE_DAY) {
        resStr = Math.floor(diff / ONE_HOUR) + "小时" + dirStr;
        // More than 23 hours, 59 minutes and 59 seconds, less than or equal to 29 days, 59 minutes and 59 seconds
      } else if (diff >= ONE_DAY && diff < 2623860000) {
        resStr = Math.floor(diff / ONE_DAY) + "天" + dirStr;
        // More than 29 days, 59 minutes, 59 seconds
      } else {
        resStr = dayjs(timeStamp).format("MM-DD-HH-mm");
      }
      return resStr;
    }
    return () => {
      return <span>{date.value}</span>;
    };
  }
});
